#ifndef __MY_SERVER__
#define __MY_SERVER__
#include "httplib.h"
#include "data.hpp"

extern cloud::DataManager *_data;

namespace cloud
{
    class Service
    {
        private:
            int _server_port;
            std::string _server_ip;
            std::string _download_prefix;
            httplib::Server _server;


        private:
            static void Upload(const httplib::Request &req, httplib::Response &rsp)
            {
                auto ret = req.has_file("file");
                if(ret == false) {
                    rsp.status = 400;
                    return;
                }
                const auto& file = req.get_file_value("file");
                std::string back_dir = Config::GetInstance()->GetBackDir();
                std::string realpath = back_dir + FileUtil(file.filename).FileName();
                FileUtil fu(realpath);
                std::string content = file.content;
                fu.SetContent(&content);
                BackupInfo info;
                info.NewBackupInfo(realpath);
                _data->Insert(info);
                rsp.status = 200;
                return;

            }
            static std::string Time(time_t t)
            {
                return std::ctime(&t);
            }
            static void ListShow(const httplib::Request &req, httplib::Response &rsp)
            {
                // 1.获取所有文件备份信息
                std::vector<cloud::BackupInfo> arry;
                _data->GetAll(&arry);

                // 2.组织html文件数据
                std::stringstream ss;
				ss << "<html><head><meta charset=\"utf-8\"><title>Download</title></head>";
				ss << "<body><h1>Download</h1><table>";
				for (auto &a : arry){
					ss << "<tr>";
					std::string filename = FileUtil(a.realpath).FileName();
					ss << "<td><a href='" << a.url << "'>" << filename << "</a></td>";
					ss << "<td align='right'>" << Time(a.mtime) << "</td>";
					ss << "<td align='right'>" << a.fsize / 1024 << "k</td>";
					ss << "</tr>";
				}
				ss << "</table></body></html>";
				rsp.body = ss.str();
				rsp.set_header("Content-Type", "text/html");
				rsp.status = 200;
                return;
            }
            static std::string GetETag(BackupInfo &info)
            {
                FileUtil fu(info.realpath);
                return fu.FileName() + "-" + std::to_string(info.fsize) + "-" + std::to_string(info.atime);
            }

            // 辅助函数：根据文件扩展名获取 MIME 类型
            static std::string getMimeType(const std::string& extension) {
                static std::unordered_map<std::string, std::string> mimeTypes = {
                {"pdf", "application/pdf"},
                {"jpg", "image/jpeg"},
                {"jpeg", "image/jpeg"},
                {"png", "image/png"},
                {"html", "text/html"},
                {"css", "text/css"},
                {"js", "application/javascript"},
                // 可以根据需要添加更多的 MIME 类型映射
                };

                auto it = mimeTypes.find(extension);
                if (it != mimeTypes.end()) {
                return it->second;
                }
                return "application/octet-stream"; // 默认类型
            }

            static void Download(const httplib::Request &req, httplib::Response &rsp)
            {
                // httplib库内置了断点续传功能，直接用就行
                BackupInfo info;
                bool ret = _data->GetOneByURL(req.path, &info);
                if(ret == false) 
                {
                    std::cout << "no such a file." << std::endl;
                    return;
                }
                if(info.pack_flag == true)
                {
                    FileUtil fu(info.packpath);
                    fu.UnCompress(info.realpath);
                    fu.Remove();
                    info.pack_flag = false;
                    _data->Update(info);
                }
                FileUtil(info.realpath).GetContent(&rsp.body);
                
                rsp.set_header("Accept-Ranges", "bytes");
                rsp.set_header("ETag", GetETag(info));
                

                // 获取文件扩展名
                // std::string extension = "";
                // size_t dot_pos = info.realpath.find_last_of('.');
                // if (dot_pos != std::string::npos) {
                //     extension = info.realpath.substr(dot_pos + 1);
                // }

                // // 根据扩展名设置 Content-Type
                // std::string mimeType = getMimeType(extension);
                // rsp.set_header("Content-Type", mimeType);
                rsp.set_header("Content-Type", "application/octet-stream");
                rsp.set_header("Charset", "UTF-8"); 
                return;

            }
        public:
            Service()
            {
                Config *config = Config::GetInstance();
                _server_port = config->GetServerPort();
                _server_ip = config->GetServerIP();
                _download_prefix = config->GetDownloadPrefix();
            }
            bool RunModule()
            {
                _server.Post("/upload", Upload);
                _server.Get("/listshow", ListShow);
                _server.Get("/", ListShow);
                std::string download_url = _download_prefix + "(.*)";
                _server.Get(download_url, Download);
                _server.listen(_server_ip.c_str(), _server_port);
                return true;
            }
        

    };
} 



#endif